/*
 * NamePickerActivity.java
 * 
 * Copyright©2012-2013 JMAS corporation. All rights reserved.
 */
package jp.co.jmas.jmasvideo;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;


import jp.co.jmas.jmasvideo.dao.ClassInfo;
import jp.co.jmas.jmasvideo.dao.DatabaseHelper;
import jp.co.jmas.jmasvideo.dao.Student;
import jp.co.jmas.jmasvideo.dao.Video;
import jp.co.jmas.jmasvideo.task.UploadVideoService;
import jp.co.jmas.jmasvideo.util.Analyzer;

import kankan.wheel.widget.OnWheelChangedListener;
import kankan.wheel.widget.OnWheelScrollListener;
import kankan.wheel.widget.WheelView;
import kankan.wheel.widget.adapters.AbstractWheelTextAdapter;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class NamePickerActivity extends Activity implements GoogleAccountManager.Callback {
	/** Intent data (type:Video) */
	public static final String KEY_VIDEO = "VIDEO";

	private Video video;

	private final static int VISIBLE_ITEMS = 7;

	private final static int REQUEST_VOICE = 1;

	private boolean scrolling = false;

	/** wheel */
	private WheelView wheelName;

	/** adapter of wheel */
	private WheelAdapter adapter;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		Bundle extras = getIntent().getExtras();
		video = new Video();
		if (extras != null) {
			video =(Video)extras.getSerializable(KEY_VIDEO);

		} else {
			Log.d("NamePickerActivity", "InvalidIntent");
			finish();
			return;
		}

		setContentView(R.layout.namepicker_layout);

		// Wheel object
		wheelName = (WheelView) findViewById(R.id.wheelName);

		// TODO データを作成
		List<ClassInfo> classList = DatabaseHelper.getClassInfoList();
		setValue(classList);
	}

	private void setValue(List<ClassInfo> classList) {
		// TODO クラスも登録しないと
		// Wheelへの名前一覧登録

		wheelName.setVisibleItems(VISIBLE_ITEMS);

		adapter = new WheelAdapter(this, classList);
		wheelName.setViewAdapter(adapter);
		wheelName.addChangingListener(new OnWheelChangedListener() {
			public void onChanged(WheelView wheel, int oldValue, int newValue) {
				if (!scrolling) {
					Student student = adapter.getStudent(newValue);
					if (student != null) {
						video.setStudent(student);
						Log.v("DrumPicker", student.getName());
					}
				}
			}
		});

		wheelName.addScrollingListener( new OnWheelScrollListener() {
			public void onScrollingStarted(WheelView wheel) {
				scrolling = true;
			}
			public void onScrollingFinished(WheelView wheel) {
				scrolling = false;
				Student student = adapter.getStudent(wheelName.getCurrentItem());
				if (student != null) {
					video.setStudent(student);
					Log.v("DrumPicker", student.getName());
				}
			}
		});

		int itemCount = adapter.getItemCount();
		if (itemCount < VISIBLE_ITEMS) {
			wheelName.setCurrentItem(itemCount / 2);
		} else {
			wheelName.setCurrentItem(VISIBLE_ITEMS / 2);
//			wheelName.setCyclic(true);
		}
	}

	public void onClickButtonSend(View view) {
		setEnabled(false);

		// タイトル
		video.setTitle("no title"); // TODO 無題

		// 説明
		video.setDesc("no description"); // TODO 無題

		// TODO 公開期限を1ヶ月とする
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, 1);
		video.setExpired(calendar.getTime());

		// STEP-1: 認証
		GoogleAccountManager.authorize(this, this);
	}

	public void onClickButtonBack(View view) {
		finish();
	}

	public void onClickButtonVoice(View view) {
		try {
			// Intent生成
			Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
			intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
			intent.putExtra(RecognizerIntent.EXTRA_PROMPT, R.string.message_voicetype);
			startActivityForResult(intent, REQUEST_VOICE); // Intent発行
		} catch (ActivityNotFoundException e) {
			// 音声入力に対応していない場合
			Toast.makeText(this, "音声入力に対応していません。", Toast.LENGTH_SHORT).show();
		}
	}

	// アクティビティ終了時に呼び出される
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// 自分が投げたインテントであれば応答する
		if (requestCode == REQUEST_VOICE) {
			// TODO
			List<ClassInfo> classList = DatabaseHelper.getClassInfoList();

			if (resultCode == RESULT_OK) {
				// 結果文字列リスト
				ArrayList<String> resultList = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
				final List<Student> candidateList = Analyzer.findCandidates(resultList, classList);

				if (candidateList.size() > 0) {
					// 候補あり
					String[] names = new String[candidateList.size()];
					for (int i=0; i<names.length; i++) {
						names[i] = Util.getStudentLabel(candidateList.get(i));
					}

					new AlertDialog.Builder(this)
						.setTitle("動画の送信先の選択") // TODO 定数化
						.setItems(names, new DialogInterface.OnClickListener(){
							public void onClick(DialogInterface dialog, int which) {
								select(candidateList.get(which));
							}
						}).show();
				} else {
					// 候補なし
					new AlertDialog.Builder(this)
						.setTitle("動画の送信先の選択") // TODO 定数化
						.setMessage("候補が見つかりませんでした")
						.setPositiveButton(android.R.string.ok, new OnClickListener(){
							@Override
							public void onClick(DialogInterface arg0, int arg1) {
								arg0.dismiss();
							}
						}).show();
				}
			}
		}

		super.onActivityResult(requestCode, resultCode, data);
	}

	private void select(Student student) {
		wheelName.setCurrentItem(adapter.getIndex(student));
	}

	public void setEnabled(boolean enabled) {
		// ボタンの非活性化
// TODO ボタンの活性化
//		findViewById(R.id.buttonUpload).setEnabled(enabled);
//		findViewById(R.id.editTitle).setEnabled(enabled);
//		findViewById(R.id.editDesc).setEnabled(enabled);
	}

	/**
	 * The simple Array wheel adapter
	 * @param <T> the element type
	 */
	public static class WheelAdapter extends AbstractWheelTextAdapter {
		private List<ClassInfo> classList;

		private String[] names;

		private int getItemCount() {
			return names.length;
		}

		/**
		 * Constructor
		 * @param context the current context
		 * @param items the items
		 */
		public WheelAdapter(Context context, List<ClassInfo> classList) {
			super(context);

			List<String> nameList = new ArrayList<String>();
			for (ClassInfo info : classList) {
				for (Student student : info.getStudentList()) {
					String name = Util.getStudentLabel(student);
					nameList.add(name);
				}
			}
			this.classList = classList;
			this.names     = nameList.toArray(new String[nameList.size()]);
		}

		@Override
		public CharSequence getItemText(int index) {
			if (index >= 0 && index < names.length) {
				return names[index];
			}
			return null;
		}

		@Override
		public int getItemsCount() {
			return names.length;
		}

		public Student getStudent(int index) {
			if (index >= 0 && index < names.length) {
				int target = 0;
				for (ClassInfo classInfo : classList) {
					List<Student> studentList = classInfo.getStudentList();
					int size = studentList.size();
					if (index < target + size) {
						return studentList.get(index - target);
					}
					target += studentList.size();
				}
			}
			return null;
		}

		/* (non-Javadoc)
		 * @see kankan.wheel.widget.adapters.AbstractWheelTextAdapter#configureTextView(android.widget.TextView)
		 */
		@Override
		protected void configureTextView(TextView view) {
			super.configureTextView(view);
			view.setGravity(Gravity.LEFT);
		}

		public int getIndex(Student target) {
			int index = 0;
			for (ClassInfo classInfo : classList) {
				for (Student student : classInfo.getStudentList()) {
					if (student.equals(target)) {
						return index;
					}
					index++;
				}
			}
			return -1;
		}
	}

	/* (non-Javadoc)
	 * @see jp.co.jmas.jmasvideo.GoogleAccountManager.Callback#success(java.lang.String, java.lang.String)
	 */
	@Override
	public void success(final String authTokenAppEngine, final String authTokenCloudStorage) {
		Student student     = video.getStudent();
		ClassInfo classInfo = student.getClassInfo();

		// アップロード・サービスの起動
		Intent intent = new Intent(this, UploadVideoService.class);
		intent.putExtra(UploadVideoService.KEY_VIDEO,    video);
		intent.putExtra(UploadVideoService.KEY_STUDENT,  student);
		intent.putExtra(UploadVideoService.KEY_CLASS,    classInfo);
		intent.putExtra(UploadVideoService.KEY_AUTHTOKEN_APPENGINE,    authTokenAppEngine);
		intent.putExtra(UploadVideoService.KEY_AUTHTOKEN_CLOUDSTORAGE, authTokenCloudStorage);
		startService(intent);

		// TODO ほかにも送りますかダイアログ。
	}

	@Override
	public void failed(String message) {
		Log.e("tag", message);
		setEnabled(true);
	}

	@Override
	public void cancel() {
		setEnabled(true);
	}
}
